package com.qq.springbootdemo.service.impl;

import com.qq.springbootdemo.common.exception.InsufficientBalanceException;
import com.qq.springbootdemo.common.exception.WalletNotFoundException;
import com.qq.springbootdemo.domain.entity.TransactionEntity;
import com.qq.springbootdemo.domain.entity.WalletEntity;
import com.qq.springbootdemo.repository.TransactionRepository;
import com.qq.springbootdemo.repository.WalletRepository;
import com.qq.springbootdemo.service.WalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

// 钱包服务实现
@Service
@Transactional
public class WalletServiceImpl implements WalletService {
    
    @Autowired
    private WalletRepository walletRepository;
    
    @Autowired
    private TransactionRepository transactionRepository;
    
    @Override
    public WalletEntity createWallet(Long userId, String currency) {
        WalletEntity wallet = WalletEntity.builder().userId(userId).currency(currency).build();
        return walletRepository.save(wallet);
    }
    
    @Override
    public WalletEntity getWallet(Long walletId) {
        return walletRepository.findById(walletId)
                .orElseThrow(() -> new WalletNotFoundException("Wallet not found: " + walletId));
    }
    
    @Override
    public BigDecimal getBalance(Long walletId) {
        WalletEntity wallet = getWallet(walletId);
        return wallet.getBalance();
    }
    
    @Override
    public void deposit(Long walletId, BigDecimal amount) {
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
        
        WalletEntity wallet = getWallet(walletId);
        BigDecimal newBalance = wallet.getBalance().add(amount);
        wallet.setBalance(newBalance);
        wallet.setUpdateTime(new Date());
        
        // 记录交易
        TransactionEntity transaction = new TransactionEntity(null, walletId, amount, "DEPOSIT");
        transaction.setStatus("SUCCESS");
        transactionRepository.save(transaction);
        
        walletRepository.save(wallet);
    }
    
    @Override
    public void withdraw(Long walletId, BigDecimal amount) throws InsufficientBalanceException {
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive");
        }
        
        WalletEntity wallet = getWallet(walletId);
        BigDecimal currentBalance = wallet.getBalance();
        
        if (currentBalance.compareTo(amount) < 0) {
            throw new InsufficientBalanceException("Insufficient balance");
        }
        
        BigDecimal newBalance = currentBalance.subtract(amount);
        wallet.setBalance(newBalance);
        wallet.setUpdateTime(new Date());
        
        // 记录交易
        TransactionEntity transaction = new TransactionEntity(walletId, null, amount, "WITHDRAW");
        transaction.setStatus("SUCCESS");
        transactionRepository.save(transaction);
        
        walletRepository.save(wallet);
    }
    
    @Override
    public void transfer(Long fromWalletId, Long toWalletId, BigDecimal amount) 
            throws InsufficientBalanceException, WalletNotFoundException {
        
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("Transfer amount must be positive");
        }
        
        if (fromWalletId.equals(toWalletId)) {
            throw new IllegalArgumentException("Cannot transfer to the same wallet");
        }
        
        WalletEntity fromWallet = getWallet(fromWalletId);
        WalletEntity toWallet = getWallet(toWalletId);
        
        if (!fromWallet.getCurrency().equals(toWallet.getCurrency())) {
            throw new IllegalArgumentException("Currency mismatch");
        }
        
        // 检查余额
        if (fromWallet.getBalance().compareTo(amount) < 0) {
            throw new InsufficientBalanceException("Insufficient balance");
        }
        
        // 创建交易记录（初始状态为PENDING）
        TransactionEntity transaction = new TransactionEntity(fromWalletId, toWalletId, amount, "TRANSFER");
        transactionRepository.save(transaction);
        
        try {
            // 扣款
            BigDecimal fromNewBalance = fromWallet.getBalance().subtract(amount);
            fromWallet.setBalance(fromNewBalance);
            fromWallet.setUpdateTime(new Date());
            
            // 收款
            BigDecimal toNewBalance = toWallet.getBalance().add(amount);
            toWallet.setBalance(toNewBalance);
            toWallet.setUpdateTime(new Date());
            
            // 更新交易状态
            transaction.setStatus("SUCCESS");
            transactionRepository.save(transaction);
            
            // 保存钱包
            walletRepository.save(fromWallet);
            walletRepository.save(toWallet);
            
        } catch (Exception e) {
            // 更新交易状态为失败
            transaction.setStatus("FAILED");
            transactionRepository.save(transaction);
            throw new RuntimeException("Transfer failed", e);
        }
    }
    
    @Override
    public List<TransactionEntity> getTransactionHistory(Long walletId) {
        return transactionRepository.findByWalletId(walletId);
    }
}